package com.smart.business.service;

import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.smart.business.dao.LocalDictDao;
import com.smart.business.dao.PointDao;
import com.smart.business.dao.PointLocationDao;
import com.smart.common.utils.AuthUtil;
import com.smart.common.utils.ThreadLocalUtil;
import com.smart.entity.business.DeptInfoVO;
import com.smart.entity.business.PointLocationEntity;
import com.smart.entity.system.DictEntity;
import com.smart.model.exception.SmartException;
import com.smart.mybatis.service.impl.BaseServiceImpl;
import com.smart.business.dao.CompanyDao;
import com.smart.entity.business.CompanyEntity;
import com.smart.service.business.CompanyService;
import groovy.util.logging.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 公司表 ServiceImpl
 *
 * @author wf
 * @since 2025-06-11 13:15:12
 */
@Service("companyService")
@Transactional(rollbackFor = Exception.class)
public class CompanyServiceImpl extends BaseServiceImpl<CompanyDao, CompanyEntity> implements CompanyService {
    @Autowired
    private CompanyDao companyDao;

    @Autowired
    private PointLocationDao pointLocationDao;
    @Autowired
    private LocalDictDao dictDao;
    @Autowired
    private PointDao pointDao;


    @Override
    public Page<CompanyEntity> getCompanyDetails(int current, int size) {
        // 1. 获取权限数据
        List<String> companyNames = ThreadLocalUtil.getPermissionResult();
        // 2. 分页查询公司详情
        Page<CompanyEntity> page = PageHelper.startPage(current, size);
        List<CompanyEntity> companyDetails = companyDao.getCompanyDetails(companyNames);

        if (companyDetails == null || companyDetails.isEmpty()) {
            return new Page<>(); // 返回空分页对象
        }

        return page;
    }


    @Override
    public Map<String, Object> getCompanyAndPointData() {
        // 1. 获取公司名称列表
        List<String> companyNames = ThreadLocalUtil.getPermissionResult();

        if (companyNames == null || companyNames.isEmpty()) {
            throw new RuntimeException("没有权限访问公司数据");
        }

        // 2. 查询公司详情
        List<CompanyEntity> companyDetails = companyDao.getCompanyDetails(companyNames);

        // 3. 构建公司信息组合数据
        List<Map<String, String>> companyInfoList = new ArrayList<>();
        for (CompanyEntity company : companyDetails) {
            Map<String, String> info = new HashMap<>();
            info.put("id", company.getId());
            info.put("companyName", company.getCompanyName());
            companyInfoList.add(info);
        }

        // 4. 查询点位信息
        List<PointLocationEntity> pointData = pointLocationDao.getPointListByCompanyNames(companyNames);

        // 5. 构造返回结果
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("companies", companyInfoList);
        resultMap.put("pointNames", pointData);

        return resultMap;
    }


    @Override
    public List<Map<String, Object>> getCurrentDict(String meterTypeId) {
        String userId = AuthUtil.getUserId();
        // 1. 通过 userId 获取到公司 id
        DeptInfoVO companyEntities = companyDao.getCompanyNameByUserId(userId);
        String companyIds = companyEntities.getId();

        if (companyIds.isEmpty()) {
            throw new RuntimeException("无法获取公司信息");
        }

        // 1. 获取完整字典结构
        List<DictEntity> allDictList = dictDao.getCurrentDict(companyIds);
        // 2. 判断是否需要根据能源类型筛选
        if (meterTypeId != null && !meterTypeId.isEmpty()) {
            // 获取具有指定能源类型的点位ID
            List<String> pointIds = pointDao.getPointIdsByMeterTypeId(meterTypeId);
            // 筛选最底层且具有指定能源类型的节点及其所有父节点
            allDictList = filterDictByEnergyType(allDictList, pointIds);
        }
        // 3. 构建树形结构
        return buildDictTree(allDictList);
    }

    @Override
    public CompanyEntity getByValues(String dictValue) {
        return Db.lambdaQuery(CompanyEntity.class)
                .eq(CompanyEntity::getSocialCode, dictValue)
                .eq(CompanyEntity::getIsDeleted, "0")
                .one();
    }

    @Override
    public List<Map<String, Object>> getProtocol() {
        // 1. 获取完整字典结构
        List<DictEntity> allProtocolList = dictDao.getProtocol();
        // 2. 构建树形结构
        return buildDictTree(allProtocolList);
    }

    /**
     * 根据能源类型筛选字典节点
     */
    private List<DictEntity> filterDictByEnergyType(List<DictEntity> allDictList, List<String> pointIds) {
        if (allDictList == null || allDictList.isEmpty()) {
            return Collections.emptyList();
        }

        if (pointIds == null || pointIds.isEmpty()) {
            return Collections.emptyList();
        }
        // 找出所有最底层节点（最大level）
        int maxLevel = allDictList.stream()
                .filter(dict -> dict.getLevel() != null)
                .mapToInt(DictEntity::getLevel)
                .max()
                .orElse(0);

        if (maxLevel <= 0) {
            return Collections.emptyList();
        }

        // 找出最底层且具有指定能源类型的节点
        Set<String> validLeafNodeIds = allDictList.stream()
                .filter(dict -> dict.getLevel() != null && dict.getLevel() == maxLevel)
                .map(DictEntity::getId)
                .filter(pointIds::contains)
                .collect(Collectors.toSet());

        if (validLeafNodeIds.isEmpty()) {
            return Collections.emptyList();
        }

        // 找出需要保留的节点（有效叶子节点及其所有祖先节点）
        return filterNodesWithAncestors(allDictList, validLeafNodeIds);
    }

    /**
     * 筛选出指定节点及其所有祖先节点
     */
    private List<DictEntity> filterNodesWithAncestors(List<DictEntity> allDictList, Set<String> targetNodeIds) {
        if (targetNodeIds.isEmpty()) {
            return Collections.emptyList();
        }

        // 创建ID到DictEntity的映射，提高查找效率
        Map<String, DictEntity> idToDictMap = allDictList.stream()
                .collect(Collectors.toMap(DictEntity::getId, Function.identity()));

        // 创建父子关系映射
        Map<String, String> parentMap = allDictList.stream()
                .collect(Collectors.toMap(DictEntity::getId, DictEntity::getParentId, (existing, replacement) -> existing));

        // 存储需要保留的节点ID
        Set<String> nodesToKeep = new HashSet<>(targetNodeIds);

        // 逐层向上查找父节点
        Set<String> currentNodes = new HashSet<>(targetNodeIds);
        while (!currentNodes.isEmpty()) {
            Set<String> parentNodes = new HashSet<>();

            for (String nodeId : currentNodes) {
                String parentId = parentMap.get(nodeId);
                // 如果父节点存在且不是根节点，且还未被标记为需要保留
                if (parentId != null && !parentId.equals("0") && !nodesToKeep.contains(parentId)) {
                    parentNodes.add(parentId);
                    nodesToKeep.add(parentId);
                }
            }

            currentNodes = parentNodes;
        }

        // 返回需要保留的节点实体
        return nodesToKeep.stream()
                .map(idToDictMap::get)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
    }

    /**
     * 构建字典树
     */
    private List<Map<String, Object>> buildDictTree(List<DictEntity> dictList) {
        Map<String, Map<String, Object>> nodeMap = new HashMap<>();
        List<Map<String, Object>> rootNodes = new ArrayList<>();

        // 创建节点映射
        for (DictEntity dict : dictList) {
            Map<String, Object> node = new HashMap<>();
            node.put("id", dict.getId());
            node.put("name", dict.getDictName());
            node.put("value", dict.getDictValue());
            node.put("parentId", dict.getParentId());
            node.put("children", new ArrayList<>());
            node.put("level", dict.getLevel());
            node.put("sort", dict.getSort());
            nodeMap.put(dict.getId(), node);
        }
        // 建立父子关系
        for (Map<String, Object> node : nodeMap.values()) {
            String parentId = (String) node.get("parentId");

            if (parentId == null || "0".equals(parentId) || !nodeMap.containsKey(parentId)) {
                rootNodes.add(node); // 根节点
            } else {
                @SuppressWarnings("unchecked")
                List<Map<String, Object>> children = (List<Map<String, Object>>) nodeMap.get(parentId).get("children");
                children.add(node);
            }
        }
        // 对所有节点的子节点按sort字段排序
        sortChildren(rootNodes);

        return rootNodes;
    }

    /**
     * 递归对子节点按sort字段排序
     */
    private void sortChildren(List<Map<String, Object>> nodes) {
        for (Map<String, Object> node : nodes) {
            @SuppressWarnings("unchecked")
            List<Map<String, Object>> children = (List<Map<String, Object>>) node.get("children");

            // 按sort字段排序
            children.sort(Comparator.comparingInt(child -> (Integer) child.get("sort")));

            // 递归排序子节点的子节点
            sortChildren(children);
        }
    }
}